package handle

import (
	"server/game/model"
	"server/game/pkg/rank"
	"server/share"

	"github.com/hwcer/cosgo/registry"
	"github.com/hwcer/cosmo"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
)

func init() {
	Register(&zset{})
}

/*
zset 排行榜
*/

type zset struct {
}

func (this *zset) Caller(node *registry.Node, handle *context.Context) interface{} {
	f := node.Method().(func(*zset, *context.Context) interface{})
	return f(this, handle)
}

type RankPlayer struct {
	*share.Player
	Rank  int64 `bson:"Rank" json:"Rank" `                 //排名
	Score int64 `bson:"score" json:"score" index:"name:" ` //积分
}

// Page 分页获取排行榜数据
func (this *zset) Page(c *context.Context) interface{} {
	args := &struct {
		cosmo.Paging
		Name   string `json:"name"`
		Circle int64  `json:"circle"`
	}{}
	if err := c.Bind(args); err != nil {
		return err
	}
	//排行信息
	args.Paging.Init(10)
	if err := rank.ZPage(args.Name, args.Circle, &args.Paging); err != nil {
		return err
	}
	if args.Paging.Record == 0 {
		return &args.Paging
	}
	var pi []string
	ps := map[string]*RankPlayer{}
	for _, p := range args.Paging.Rows.([]*rank.Player) {
		pi = append(pi, p.Uid)
		ps[p.Uid] = &RankPlayer{Score: p.Score, Rank: p.Rank}
	}
	//角色信息
	player := &share.Player{}
	var dest []*share.Player
	tx := db.Model(&model.Role{}).Select(player.GetDBFields()...)
	tx = tx.Where("_id IN ?", pi)
	if err := tx.Find(&dest).Error; err != nil {
		return err
	}
	for _, v := range dest {
		if p := ps[v.Uid]; p != nil {
			p.Player = v
		}
	}
	//整理成有序列表
	var ret []*RankPlayer
	for _, k := range pi {
		if v := ps[k]; v != nil && v.Player != nil {
			ret = append(ret, v)
		}
	}
	args.Paging.Rows = ret

	return &args.Paging
}

// Rank 个人排行信息
// uid默认本人
func (this *zset) Rank(c *context.Context) interface{} {
	args := &struct {
		Uid    string `json:"uid"`
		Name   string `json:"name"`
		Circle int64  `json:"circle"`
	}{}

	if err := c.Bind(args); err != nil {
		return err
	}
	if args.Uid == "" {
		args.Uid = c.Uid()
	}
	if r, err := rank.ZRank(args.Name, args.Circle, args.Uid, true); err != nil {
		return err
	} else {
		return r
	}
}

// Circle 查询排行榜当前届数
// name string 排行榜名称
// skip int 偏移量，0：当前
func (this *zset) Circle(c *context.Context) interface{} {
	name := c.GetString("name")
	if name == "" {
		return errors.ErrArgEmpty
	}
	skip := c.GetInt64("skip")
	return rank.Cycle(name, skip)
}
